﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StyleMVVM.DependencyInjection;
using StyleMVVM.ViewModel;
using System.ComponentModel;
using Wala.Connection.Objects.Timeline;
using StyleMVVM.View;
using System.Collections.ObjectModel;
using Wala.Connection.Managements;
using Windows.UI.Popups;
using Wala.Connection.Objects.Contacts;
using Windows.UI.Xaml.Controls;
using Wala.Connection.Helpers;
using Wala.Connection.Objects.Authen;
using Wala.Connection.Objects.Profiles;

namespace Wala.ViewModels.Timelines
{
    public class TimelineDetailPageViewModel : PageViewModel, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        #region //------------ Private Fields ----------//

        private string displayName;
        private string commentText;
        private TimelineInfo curTimeline;
        private ObservableCollection<TimelineInfo> timelines;
        private ObservableCollection<UserInfo> userLikes;
        private ObservableCollection<Comment> comments;
        private string showButtonAction = "Collapsed";
        private EventCommand itemSelectedCommand;
        private EventCommand gotFocus;
        private DelegateCommand addCommentCommand;
        private DelegateCommand doLikeCommand;

        #endregion

        #region //------------ CLR Properties ----------//

        public TimelineInfo CurTimeline
        {
            get { return curTimeline; }
            set 
            {
                if (curTimeline != value)
                {
                    curTimeline = value;
                    OnPropertyChanged("CurTimeline");
                }
            }
        }

        public string DisplayName
        {
            get { return displayName; }
            set 
            {
                if (displayName != value)
                {
                    displayName = value;
                    OnPropertyChanged("DisplayName");
                }
            }
        }

        public string CommentText
        {
            get { return commentText; }
            set 
            {
                if (commentText != value)
                {
                    commentText = value;
                    OnPropertyChanged("CommentText");
                }
            }
        }

        public ObservableCollection<UserInfo> UserLikes
        {
            get { return userLikes; }
            set 
            {
                if (userLikes != value)
                {
                    userLikes = value;
                    OnPropertyChanged("UserLikes");
                }
            }
        }

        public ObservableCollection<Comment> Comments
        {
            get { return comments; }
            set 
            {
                if (comments != value)
                {
                    comments = value;
                    OnPropertyChanged("Comments");
                }
            }
        }

        public ObservableCollection<TimelineInfo> Timelines
        {
            get { return timelines; }
            set
            {
                if (timelines != value)
                {
                    timelines = value;
                    OnPropertyChanged("Timelines");
                }
            }
        }

        public string ShowButtonAction
        {
            get { return showButtonAction; }
            set 
            {
                if (showButtonAction != value)
                {
                    showButtonAction = value;
                    OnPropertyChanged("ShowButtonAction");
                }
            }
        }

        public EventCommand ItemSelectedCommand
        {
            get
            {
                if (itemSelectedCommand == null)
                {
                    itemSelectedCommand = new EventCommand(itemSelectedHandler);
                }
                return itemSelectedCommand;
            }
        }

        public EventCommand GotFocus
        {
            get
            {
                if (gotFocus == null)
                {
                    gotFocus = new EventCommand(LostFocusHandler);
                }
                return gotFocus;
            }
        }

        public DelegateCommand AddCommentCommand
        {
            get 
            {
                if (addCommentCommand == null)
                {
                    addCommentCommand = new DelegateCommand(AddCommentExcute);
                }
                return addCommentCommand; 
            }            
        }

        public DelegateCommand DoLikeCommand
        {
            get 
            {
                if (doLikeCommand == null)
                {
                    doLikeCommand = new DelegateCommand(DoLikeCommandExcute);
                }
                return doLikeCommand; 
            }            
        }

        #endregion

        #region //------------ Pubic Methods ----------//



        #endregion

        #region //------------ Private Methods ----------//

        private async void itemSelectedHandler(object sender, object args, object parameter)
        {
            SelectionChangedEventArgs selectedEventArgs = args as SelectionChangedEventArgs;

            if (selectedEventArgs != null)
            {
                List<UserInfo> lstUserLike = await TimelineManager.GetUserLikeList(CurTimeline.Id, CurTimeline.Type, 0, -1);
                UserLikes = new ObservableCollection<UserInfo>();
                if (lstUserLike != null)
                {
                    foreach (UserInfo item in lstUserLike)
                    {
                        UserLikes.Add(item);
                    }
                }

                Comments = new ObservableCollection<Comment>();
                List<Comment> lstComment = await TimelineManager.GetCommentListAsync(CurTimeline.Id, CurTimeline.Type, 0, -1);
                for (int i = lstComment.Count - 1; i >= 0; i--)
                {
                    this.Comments.Add(lstComment[i]);
                }
            }
            else
            {
                Log.Error("Missed ItemClickEventArgs args");
            }
        }

        private void LostFocusHandler(object sender, object args, object parameter)
        {
            ShowButtonAction = "Visible";
        }

        private async void AddCommentExcute(object parameter)
        {
            var objectStorageHelper = new StorageHelper<ShortProfile>(StorageType.Local);
            ShortProfile curUser = await objectStorageHelper.LoadASync("CurrentUser");

            long commentId = await TimelineManager.CreateComment(CommentText, CurTimeline.Id, CurTimeline.Type, CurTimeline.Location_X,CurTimeline.Location_Y);            
            long timeStamp =
                (long)(DateTime.Now - DateTime.Parse("01/01/1970 00:00:00").ToLocalTime()).TotalSeconds;

            var newComment = new Comment()
            {
                Owner_Display_Name = curUser.Display_name,
                Owner_Avatar_Id = curUser.Avatar_id,
                Text = CommentText,
                Time_Stamp = timeStamp
            };

            this.Comments.Add(newComment);
            CurTimeline.Number_Of_Comments += 1;            

            if (commentId == 0)
            {
                this.Comments.Remove(newComment);
                CurTimeline.Number_Of_Comments -= 1;
            }
            else
            {
                newComment.Comment_ID = commentId;
                CommentText = String.Empty;
            }
            
        }

        private async void DoLikeCommandExcute(object parameter)
        {
            var objectStorageHelper = new StorageHelper<ShortProfile>(StorageType.Local);
            ShortProfile curUser = await objectStorageHelper.LoadASync("CurrentUser");

            UserInfo userLike = new UserInfo();

            bool success = false;

            if (CurTimeline.User_Like)
            {
                userLike = UserLikes.Where(x=>x.User_ID == curUser.Uid).FirstOrDefault();

                // Pre-showing to user
                CurTimeline.User_Like = false;
                CurTimeline.Number_Of_Likes -= 1;
                UserLikes.Remove(userLike);

                success = await TimelineManager.DoUnLike(CurTimeline.Id, CurTimeline.Type, CurTimeline.Location_X.ToString(), CurTimeline.Location_Y.ToString());
                
                if (!success)
                {
                    CurTimeline.User_Like = true;
                    CurTimeline.Number_Of_Likes += 1;
                    UserLikes.Add(userLike);
                }
            }
            else
            {
                userLike = new UserInfo(curUser.Uid, curUser.Display_name, curUser.Avatar_id, curUser.Cover_id);

                // Pre-show to user
                CurTimeline.User_Like = true;
                CurTimeline.Number_Of_Likes += 1;
                UserLikes.Add(userLike);
                success = await TimelineManager.DoLike(CurTimeline.Id, CurTimeline.Type, CurTimeline.Location_X.ToString(), CurTimeline.Location_Y.ToString());

                if (!success)
                {
                    CurTimeline.User_Like = false;
                    CurTimeline.Number_Of_Likes -= 1;
                    UserLikes.Remove(userLike);
                }
            }
        }
        

        #endregion

        #region //----------- Protected Methods ----------//

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        protected override async void OnNavigatedTo(object sender, StyleNavigationEventArgs e)
        {
            Dictionary<string, object> param = NavigationParameter as Dictionary<string, object>;
            
            ContactBasic contact = param["Contact"] as ContactBasic;
            DisplayName = contact.Friend_display_name;

            List<TimelineInfo> lstTimeline = new List<TimelineInfo>();            
            lstTimeline = await TimelineManager.GetFriendTimeline(contact.Friend_id, 0, 9);
            Timelines = new ObservableCollection<TimelineInfo>();
            foreach (TimelineInfo timeline in lstTimeline)
            {
                Timelines.Add(timeline);   
                if(timeline.Id==(param["CurTimeline"] as TimelineInfo).Id)
                {
                    CurTimeline = timeline;
                }
            }
        }

        #endregion
    }
}
